!############################# Change Log ##################################
! 5.0.0
!
!###########################################################################
!  Copyright (C)  1990, 1995, 1999, 2000, 2003 - All Rights Reserved
!  Regional Atmospheric Modeling System - RAMS
!###########################################################################

subroutine masterput_oda()

  use mem_oda

  use rpara, only: &
       nmachs,     & ! INTENT(IN)
       machnum       ! INTENT(IN)

  implicit none

  !   +------------------------------------------------------------------
  !   ! This routine gives obs data to the nodes for ODA. All obs are sent 
  !   !    to all nodes.
  !   +------------------------------------------------------------------
  real, allocatable :: buff(:)
  integer :: nwords, nm, ns, max_size, ipos, tag
  
  nwords = 12 + 7 * maxodagrids + 6
  call parf_pack_max_size(nwords, max_size)
  allocate (buff(max_size))

  ! Namelist info
  ipos = 1
  call parf_pack_real(wt_oda_grid, maxodagrids, buff, max_size, ipos)
  call parf_pack_real(frqoda,      1,           buff, max_size, ipos)
  call parf_pack_real(todabeg,     1,           buff, max_size, ipos)
  call parf_pack_real(todaend,     1,           buff, max_size, ipos)
  call parf_pack_real(tnudoda,     1,           buff, max_size, ipos)
  call parf_pack_real(wt_oda_uv,   1,           buff, max_size, ipos)
  call parf_pack_real(wt_oda_th,   1,           buff, max_size, ipos)
  call parf_pack_real(wt_oda_pi,   1,           buff, max_size, ipos)
  call parf_pack_real(wt_oda_rt,   1,           buff, max_size, ipos)
  call parf_pack_real(oda_sfc_til, 1,           buff, max_size, ipos)
  call parf_pack_real(oda_sfc_tel, 1,           buff, max_size, ipos)
  call parf_pack_real(oda_upa_til, 1,           buff, max_size, ipos)
  call parf_pack_real(oda_upa_tel, 1,           buff, max_size, ipos)
  call parf_pack_real(roda_sfce,   maxodagrids, buff, max_size, ipos)
  call parf_pack_real(roda_sfc0,   maxodagrids, buff, max_size, ipos)
  call parf_pack_real(roda_upae,   maxodagrids, buff, max_size, ipos)
  call parf_pack_real(roda_upa0,   maxodagrids, buff, max_size, ipos)
  call parf_pack_real(roda_zfact,  maxodagrids, buff, max_size, ipos)
  call parf_pack_real(roda_hgt,    maxodagrids, buff, max_size, ipos)
  
  ! Sizes for arrays
  call parf_pack_int (num_oda_sfc,  1, buff, max_size, ipos)
  call parf_pack_int (nsfcfiles,    1, buff, max_size, ipos)
  call parf_pack_int (maxtimes_sfc, 1, buff, max_size, ipos)
  call parf_pack_int (num_oda_upa,  1, buff, max_size, ipos)
  call parf_pack_int (nupafiles,    1, buff, max_size, ipos)
  call parf_pack_int (maxtimes_upa, 1, buff, max_size, ipos)
  
  tag = 212
  do nm=1,nmachs
     call parf_send_block(buff, max_size, machnum(nm), tag)
  enddo
  
  deallocate (buff)

  ! Surface obs
  
  nwords= num_oda_sfc*( 9 + 3*maxodagrids + 8*maxtimes_sfc)
  call parf_pack_max_size(nwords, max_size)
  allocate (buff(max_size))

  ipos = 1
  do ns=1,num_oda_sfc
     call parf_pack_char(oda_sfc_info(ns)%id,         8, buff, max_size, ipos)
     call parf_pack_int (oda_sfc_info(ns)%intid,      1, buff, max_size, ipos)
     call parf_pack_int (oda_sfc_info(ns)%ntimes,     1, buff, max_size, ipos)
     call parf_pack_int (oda_sfc_info(ns)%iactive(1), &
          maxodagrids, buff, max_size, ipos)
     call parf_pack_real  (oda_sfc_info(ns)%xista(1),   maxodagrids, &
          buff, max_size, ipos)
     call parf_pack_real  (oda_sfc_info(ns)%xjsta(1),   maxodagrids, &
          buff, max_size, ipos)
     call parf_pack_real(oda_sfc_info(ns)%xlat,         1, buff, max_size, ipos)
     call parf_pack_real(oda_sfc_info(ns)%xlon,         1, buff, max_size, ipos)
     call parf_pack_real(oda_sfc_info(ns)%xsta,         1, buff, max_size, ipos)
     call parf_pack_real(oda_sfc_info(ns)%ysta,         1, buff, max_size, ipos)
     call parf_pack_real(oda_sfc_info(ns)%stopo,        1, buff, max_size, ipos)
     
     call parf_pack_real(oda_sfc_obs(ns)%time(1),       maxtimes_sfc, &
          buff, max_size, ipos)
     call parf_pack_real(oda_sfc_obs(ns)%temp(1),       maxtimes_sfc, &
          buff, max_size, ipos)
     call parf_pack_real(oda_sfc_obs(ns)%dewpt(1),      maxtimes_sfc, &
          buff, max_size, ipos)
     call parf_pack_real(oda_sfc_obs(ns)%us(1),         maxtimes_sfc, &
          buff, max_size, ipos)
     call parf_pack_real(oda_sfc_obs(ns)%vs(1),         maxtimes_sfc, &
          buff, max_size, ipos)
     call parf_pack_real(oda_sfc_obs(ns)%u(1),          maxtimes_sfc, &
          buff, max_size, ipos)
     call parf_pack_real(oda_sfc_obs(ns)%v(1),          maxtimes_sfc, &
          buff, max_size, ipos)
     call parf_pack_real(oda_sfc_obs(ns)%ps(1),         maxtimes_sfc, &
          buff, max_size, ipos)
  enddo
  
  tag = 213
  do nm=1,nmachs
     call parf_send_block(buff, max_size, machnum(nm), tag)
  enddo

  deallocate (buff)

  ! Upper air obs
  
  nwords= num_oda_upa*( 9 + 3*maxodagrids + 3*maxtimes_upa + &
       9*maxupalevs*maxtimes_upa)
  call parf_pack_max_size(nwords, max_size)
  allocate (buff(max_size))

  ipos = 1
  do ns=1,num_oda_upa
     call parf_pack_char(oda_upa_info(ns)%id,         8, buff, max_size, ipos)
     call parf_pack_int (oda_upa_info(ns)%intid,      1, buff, max_size, ipos)
     call parf_pack_int (oda_upa_info(ns)%ntimes,     1, buff, max_size, ipos)
     call parf_pack_int (oda_upa_info(ns)%iactive(1), maxodagrids, &
          buff, max_size, ipos)
     call parf_pack_real(oda_upa_info(ns)%xista(1),   maxodagrids, &
          buff, max_size, ipos)
     call parf_pack_real(oda_upa_info(ns)%xjsta(1),   maxodagrids, &
buff, max_size, ipos)
     call parf_pack_real(oda_upa_info(ns)%xlat,       1, buff, max_size, ipos)
     call parf_pack_real(oda_upa_info(ns)%xlon,       1, buff, max_size, ipos)
     call parf_pack_real(oda_upa_info(ns)%xsta,       1, buff, max_size, ipos)
     call parf_pack_real(oda_upa_info(ns)%ysta,       1, buff, max_size, ipos)
     call parf_pack_real(oda_upa_info(ns)%stopo,      1, buff, max_size, ipos)
     
     call parf_pack_real(oda_upa_obs(ns)%time(1),     maxtimes_upa, &
          buff, max_size, ipos)
     call parf_pack_real(oda_upa_obs(ns)%lp  (1),     maxtimes_upa, &
          buff, max_size, ipos)
     call parf_pack_real(oda_upa_obs(ns)%lz  (1),     maxtimes_upa, &
          buff, max_size, ipos)
     call parf_pack_real(oda_upa_obs(ns)%theta(1,1),  maxupalevs*maxtimes_upa,&
          buff, max_size, ipos)
     call parf_pack_real(oda_upa_obs(ns)%rv   (1,1),  maxupalevs*maxtimes_upa,&
          buff, max_size, ipos)
     call parf_pack_real(oda_upa_obs(ns)%us   (1,1),  maxupalevs*maxtimes_upa,&
 buff, max_size, ipos)
     call parf_pack_real(oda_upa_obs(ns)%vs   (1,1),  maxupalevs*maxtimes_upa,&
          buff, max_size, ipos)
     call parf_pack_real(oda_upa_obs(ns)%zz   (1,1),  maxupalevs*maxtimes_upa,&
          buff, max_size, ipos)
     call parf_pack_real(oda_upa_obs(ns)%u    (1,1),  maxupalevs*maxtimes_upa,&
          buff, max_size, ipos)
     call parf_pack_real(oda_upa_obs(ns)%v    (1,1),  maxupalevs*maxtimes_upa,&
          buff, max_size, ipos)
     call parf_pack_real(oda_upa_obs(ns)%pi   (1,1),  maxupalevs*maxtimes_upa,&
          buff, max_size, ipos)
     call parf_pack_real(oda_upa_obs(ns)%zgeo (1,1),  maxupalevs*maxtimes_upa,&
          buff, max_size, ipos)
  enddo

  tag = 214
  do nm=1,nmachs
     call parf_send_block(buff, max_size, machnum(nm), tag)
  enddo
  
  deallocate (buff)

end subroutine masterput_oda


!     ****************************************************************

subroutine nodeget_oda()

  use node_mod
  use mem_oda

  implicit none

  real, allocatable :: buff(:)
  integer :: nwords, ns, ipos, max_size, tag


  nwords = 12 + 7 * maxodagrids + 6
  call parf_pack_max_size(nwords, max_size)
  allocate (buff(max_size))

  tag = 212
  call parf_get_block(buff, max_size, master_num, tag)

  ! Namelist info
  ipos = 1
  call parf_unpack_real(buff, max_size, ipos, wt_oda_grid, maxodagrids)
  call parf_unpack_real(buff, max_size, ipos, frqoda, 1)
  call parf_unpack_real(buff, max_size, ipos, todabeg, 1)
  call parf_unpack_real(buff, max_size, ipos, todaend, 1)
  call parf_unpack_real(buff, max_size, ipos, tnudoda, 1)
  call parf_unpack_real(buff, max_size, ipos, wt_oda_uv, 1)
  call parf_unpack_real(buff, max_size, ipos, wt_oda_th, 1)
  call parf_unpack_real(buff, max_size, ipos, wt_oda_pi, 1)
  call parf_unpack_real(buff, max_size, ipos, wt_oda_rt, 1)
  call parf_unpack_real(buff, max_size, ipos, oda_sfc_til, 1)
  call parf_unpack_real(buff, max_size, ipos, oda_sfc_tel, 1)
  call parf_unpack_real(buff, max_size, ipos, oda_upa_til, 1)
  call parf_unpack_real(buff, max_size, ipos, oda_upa_tel, 1)
  call parf_unpack_real(buff, max_size, ipos, roda_sfce, maxodagrids)
  call parf_unpack_real(buff, max_size, ipos, roda_sfc0, maxodagrids)
  call parf_unpack_real(buff, max_size, ipos, roda_upae, maxodagrids)
  call parf_unpack_real(buff, max_size, ipos, roda_upa0, maxodagrids)
  call parf_unpack_real(buff, max_size, ipos, roda_zfact, maxodagrids)
  call parf_unpack_real(buff, max_size, ipos, roda_hgt, maxodagrids)

  ! Sizes for arrays
  call parf_unpack_int (buff, max_size, ipos, num_oda_sfc, 1)
  call parf_unpack_int (buff, max_size, ipos, nsfcfiles, 1)
  call parf_unpack_int (buff, max_size, ipos, maxtimes_sfc, 1)
  call parf_unpack_int (buff, max_size, ipos, num_oda_upa, 1)
  call parf_unpack_int (buff, max_size, ipos, nupafiles, 1)
  call parf_unpack_int (buff, max_size, ipos, maxtimes_upa, 1)

  deallocate (buff)

  ! Allocate main obs arrays

  call oda_obs_alloc()

  ! Surface obs

  nwords= num_oda_sfc*( 9 + 3*maxodagrids + 8*maxtimes_sfc)
  call parf_pack_max_size(nwords, max_size)
  allocate (buff(max_size))

  tag = 213
  call parf_get_block(buff, max_size, master_num, tag)

  ipos = 1
  do ns=1,num_oda_sfc
     call parf_unpack_char(buff, max_size, ipos, oda_sfc_info(ns)%id, 8)
     call parf_unpack_int (buff, max_size, ipos, oda_sfc_info(ns)%intid, 1)
     call parf_unpack_int (buff, max_size, ipos, oda_sfc_info(ns)%ntimes, 1)
     call parf_unpack_int (buff, max_size, ipos, oda_sfc_info(ns)%iactive(1), maxodagrids)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_sfc_info(ns)%xista(1), maxodagrids)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_sfc_info(ns)%xjsta(1), maxodagrids)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_sfc_info(ns)%xlat, 1)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_sfc_info(ns)%xlon, 1)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_sfc_info(ns)%xsta, 1)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_sfc_info(ns)%ysta, 1)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_sfc_info(ns)%stopo, 1)

     call parf_unpack_real(buff, max_size, ipos, &
          oda_sfc_obs(ns)%time(1) , maxtimes_sfc)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_sfc_obs(ns)%temp(1) , maxtimes_sfc)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_sfc_obs(ns)%dewpt(1), maxtimes_sfc)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_sfc_obs(ns)%us(1)   , maxtimes_sfc)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_sfc_obs(ns)%vs(1)   , maxtimes_sfc)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_sfc_obs(ns)%u (1)   , maxtimes_sfc)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_sfc_obs(ns)%v (1)   , maxtimes_sfc)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_sfc_obs(ns)%ps(1)   , maxtimes_sfc)
  enddo

  deallocate (buff)

  ! Upper air obs

  nwords= num_oda_upa*( 9 + 3*maxodagrids + 3*maxtimes_upa  &
       + 9*maxupalevs*maxtimes_upa)
  call parf_pack_max_size(nwords, max_size)
  allocate (buff(max_size))
  
  tag = 214
  call parf_get_block(buff, max_size, master_num, tag)

  ipos = 1
  do ns=1,num_oda_upa
     call parf_unpack_char(buff, max_size, ipos, oda_upa_info(ns)%id, 8)
     call parf_unpack_int (buff, max_size, ipos, oda_upa_info(ns)%intid, 1)
     call parf_unpack_int (buff, max_size, ipos, oda_upa_info(ns)%ntimes, 1)
     call parf_unpack_int (buff, max_size, ipos, oda_upa_info(ns)%iactive(1), maxodagrids)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_upa_info(ns)%xista(1), maxodagrids)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_upa_info(ns)%xjsta(1), maxodagrids)
     call parf_unpack_real(buff, max_size, ipos, oda_upa_info(ns)%xlat, 1)
     call parf_unpack_real(buff, max_size, ipos, oda_upa_info(ns)%xlon, 1)
     call parf_unpack_real(buff, max_size, ipos, oda_upa_info(ns)%xsta, 1)
     call parf_unpack_real(buff, max_size, ipos, oda_upa_info(ns)%ysta, 1)
     call parf_unpack_real(buff, max_size, ipos, oda_upa_info(ns)%stopo, 1)

     call parf_unpack_real(oda_upa_obs(ns)%time(1),maxtimes_upa)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_upa_obs(ns)%lp  (1), maxtimes_upa)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_upa_obs(ns)%lz  (1), maxtimes_upa)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_upa_obs(ns)%theta(1, 1),maxupalevs*maxtimes_upa)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_upa_obs(ns)%rv   (1, 1),maxupalevs*maxtimes_upa)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_upa_obs(ns)%us   (1, 1),maxupalevs*maxtimes_upa)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_upa_obs(ns)%vs   (1, 1),maxupalevs*maxtimes_upa)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_upa_obs(ns)%zz   (1, 1),maxupalevs*maxtimes_upa)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_upa_obs(ns)%u    (1, 1),maxupalevs*maxtimes_upa)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_upa_obs(ns)%v    (1, 1),maxupalevs*maxtimes_upa)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_upa_obs(ns)%pi   (1, 1),maxupalevs*maxtimes_upa)
     call parf_unpack_real(buff, max_size, ipos, &
          oda_upa_obs(ns)%zgeo (1, 1),maxupalevs*maxtimes_upa)
  enddo

  deallocate (buff)

end subroutine nodeget_oda
